<template>
  <div style="margin-top: 30px;">
    <!-- 数据库类型选框 -->
    <MySelect title="数据库类型：" v-model="select.databaseType">
      <MyOption v-for="(dt,index) in Object.keys(db)" 
        :key="index" 
        :value="index+1" 
        :label="dt"
      />
      <MyOption value="0" label="&nbsp;"/>
    </MySelect>

    <!-- 系统名称选框 -->
    <MySelect title="系统名称：" v-model="select.systemName">
      <MyOption v-for="(sn,index) in getSystemName()" 
        :key="index" 
        :value="index+1" 
        :label="sn"
      />
      <MyOption value="0" label="&nbsp;"/>
    </MySelect>

    <!-- 数据库名选框 -->
    <MySelect title="数据库名：" v-model="select.databaseName">
      <MyOption v-for="(d, index) in getDatabase()" 
        :key="index" 
        :value="index+1" 
        :label="d.dbName"
      />
      <MyOption :value="0" label="&nbsp;"/>
    </MySelect>

    <!-- 运行按钮 -->
    <LoginButton style="margin-left: 50px;" type=2 title="Run 运行" @click="runCode()"/>

    <!-- 分割线 -->
    <hr style="color: rgba(0, 0, 0, 0.1); margin-top: 30px;">

    <!-- 代码输入区域 -->
    <CodeBoard v-model="allCode"
      @mouseup="getSelectCode()"
      @change="getSelectCode()"
    ></CodeBoard>

    <!-- 运行结果区域 -->
    <div class="results-container shadow">
      运行结果：
      <span @click="resultsError = []; results = []" class="clearBtn pointer" style="float: right;">Clear</span>
      <el-collapse v-model="activeNames" @change="handleChange" style="margin-top: 10px;">
        <el-collapse-item 
          v-for="(r,index) of results" 
          :key="index" 
          :title="'Result '+(index+1)" 
          :name="index"
        >
          <div>{{ resultsError[index] }}</div>
          <div v-if="resultsError[index] == '运行成功！'" class="results-table-container shadow">
            <!-- 表格显示 -->
            <table>
              <thead>
                <tr>
                  <td v-for="(p,index) in Object.keys(r[0])" :key="index">{{ p }}</td>
                </tr>
              </thead>
              <tbody>
                <tr v-for="(data,dIndex) in r" :key="dIndex">
                  <td v-for="(dp, dpIndex) in data" :key="dpIndex">
                    {{ dp }}
                  </td>
                </tr>
              </tbody>
            </table>
          </div>
        </el-collapse-item>
      </el-collapse>
    </div>
    

  </div>
</template>

<script>
import MySelect from './MySelect.vue'
import MyOption from './MyOption.vue'
import LoginButton from './LoginButton.vue';
import CodeBoard from './CodeBoard.vue'
import request from '@/utils/request';

export default {
  name: 'SqlPage',
  props: ['user'],
  components:{
    MySelect,
    MyOption,
    LoginButton,
    CodeBoard
},
  data(){
    return{
      allCode: '',
      selectCode: '',
      database: {
        MySql: [
          {
            databaseName: 'users'
          },
          {
            databaseName: 'managers'
          },
          {
            databaseName: 'op'
          },
        ],
        Oracle: [],
        SqlServer: [],
        PostgreSql: [],
      },
      select: {
        databaseType: 0,
        systemName: 0,
        databaseName: 0,
      },
      results:[
      ],
      resultsError:[],
      /* 后端数据库传来的数据 */
      serverData:[]
    }
  },
  computed:{
    /* 分好类别的serverData */
    db(){
      let fmData = {}

      /* 遍历服务器传来的数据源信息 */
      this.serverData.forEach(element => {
        switch (element.dbType) {
          case 'mysql':
            element.dbType = 'Mysql'
            break;
          case 'oracle':
            element.dbType = 'Oracle'
            break;
          case 'sqlserver':
            element.dbType = 'SqlServer'
            break;
          default:
            if(element.dbType && element.dbType.length > 0){
              element.dbType = element.dbType[0].toUpperCase() + element.dbType.slice(1).toLowerCase()
            }
            break;
        }

        /* 如果fmData有与该数据源相匹配的属性名 */
        if(fmData[element.dbType]){
          if(fmData[element.dbType][element.systemName]){
            fmData[element.dbType][element.systemName].push(element)
          }else{
            fmData[element.dbType][element.systemName] = []
            fmData[element.dbType][element.systemName].push(element)
          }
        /* 如果fmData没有与该数据源相匹配的属性名 */
        }else{
          fmData[element.dbType] = {}
          fmData[element.dbType][element.systemName] = []
          fmData[element.dbType][element.systemName].push(element)
        }
      });

      return fmData
    },
    /* 用户选择的数据库信息 */
    selectDb(){
      return this.getDatabase()[this.select.databaseName-1]
    }
  },
  methods:{
    /* 获取鼠标选中的代码放在selectCode里 */
    getSelectCode(){
      this.selectCode = window.getSelection().toString()
      console.log(this.selectCode);
    },
    /* 获取已选择数据库类型下的所有数据库系统名称 */
    getSystemName(){
      if(!this.db[Object.keys(this.db)[this.select.databaseType-1]])
        return undefined
      else{
        return Object.keys(this.db[Object.keys(this.db)[this.select.databaseType-1]]) 
      }
    },
    /* 获取已选择数据库系统名称下的所有数据库 */
    getDatabase(){
      let sn = this.getSystemName()
      if(sn){
        return this.db[Object.keys(this.db)[this.select.databaseType-1]][sn[this.select.systemName-1]]
      }else{
        return undefined
      }
    },
    getAllSource(){
      request.get('/newapi/data/getAllSource').then(
        res => {
          /* console.log(res.data); */
          this.serverData = res.data
        },
        error => {console.log(error);}
      )
    },
    runCode(){
      /* 判断是否有选择数据库 */
      if(this.select.databaseName == 0){
        this.$message({
          message: '请选择数据库信息',
          type: 'error'
        })
        return
      }

      /* 判断是否有输入Sql语句 */
      if(this.allCode.trim() == ""){
        this.$message({
          message: '请输入Sql语句进行查询',
          type: 'error'
        })
        return
      }
      

      let params = {
        sql: this.allCode,
        'findDbModel.dbType': this.selectDb.dbType,
        'findDbModel.dbName': this.selectDb.dbName,
        'findDbModel.systemName': this.selectDb.systemName,
        pageNum: 1,
        pageSize: 99999,
      }

      /* 用户鼠标选中的代码如果为空则运行全部，不为空则运行选中的部分 */
      params.sql = this.selectCode.trim() == ""? this.allCode : this.selectCode

      console.log(params);
      request.get('/newapi/data/run', {params}).then(
        res => { 
          if(res.code == "200" && res.data.length > 0){
            console.log(res); 
            this.results.push(res.data)
            this.resultsError.push("运行成功！")
            this.$message({
              message:"运行成功！",
              type:'success'
            }) 
          }else{
            console.log(1,res);
            this.results.push({})
            this.resultsError.push("运行错误！")
            this.$message({
              message:"运行错误！",
              type:'error'
            }) 
          }
        },
        () => { 
          this.results.push({})
          this.resultsError.push("运行错误！") 
          this.$message({
            message:"运行错误！",
            type:'error'
          })
        }
      )
    }
  },
  mounted(){
    this.getAllSource()
  },
}
</script>

<style scoped lang="less">
select {
  height: 40px;
  width: 150px;
  border-radius: 10px;
}

select option {
  border-radius: 10px;
}

.results-table-container {
  width: 97%;
  margin-top: 20px;
  margin-left: 20px;
  margin-right: auto;
  border-radius: 10px;
  overflow: auto;
  max-height: 500px;
}
.results-container {
  border-radius: 10px;
  overflow: hidden;
  padding: 20px;
  background-color: white;
  margin-top: 20px;

  table {
    min-width: 100%;
    background-color: rgb(199, 199, 199);
    border-radius: 10px;
    border-collapse: collapse;
    overflow: hidden;
    table-layout: fixed;
  }

  tbody tr:nth-child(2n + 1) {
    background-color: rgb(228, 228, 228);
  }

  tbody tr:hover {
    background-color: rgb(255, 255, 255);
  }

  tr {
    height: 50px;
  }

  tr td {
    padding-left: 10px;
    padding-top: 5px;
    padding-bottom: 5px;
    min-width: 100px;
  }

  thead {
    font-weight: bold;
  }
}

.clearBtn {
  transition: all 0.2s;
  color: brown;
  font-weight: bold;
  text-decoration: underline;
}
.clearBtn:hover {
  transition: all 0.2s;
  color: rgb(248, 53, 53);
  font-weight: bold;
  text-decoration: underline;
}
</style>
